package com.zmj.sy.mom.srv.aps.utils.order.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zmj.sy.mom.srv.aps.bean.bo.PhaseAccessoriesWrap;
import com.zmj.sy.mom.srv.aps.bean.entity.base.BaseEntity;
import com.zmj.sy.mom.srv.aps.bean.entity.base.PhaseJob;
import com.zmj.sy.mom.srv.aps.bean.entity.base.PhaseJobRef;
import com.zmj.sy.mom.srv.aps.bean.entity.order.*;
import com.zmj.sy.mom.srv.aps.bean.entity.resource.Customer;
import com.zmj.sy.mom.srv.aps.bean.entity.resource.Factory;
import com.zmj.sy.mom.srv.aps.bean.entity.resource.Phase;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BaseListResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BasePageResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.order.*;
import com.zmj.sy.mom.srv.aps.mapper.*;
import com.zmj.sy.mom.srv.aps.utils.*;
import com.zmj.sy.mom.srv.aps.utils.nest.NestRule;
import com.zmj.sy.mom.srv.aps.utils.order.ExternalOrder;
import com.zmj.sy.mom.srv.mbd.api.api.MomSrvMbdApiClient;
import com.zmj.sy.mom.srv.mbd.api.bean.dto.bominfo.BomInfoTreeResDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Component
public class MbdExternalOrder implements ExternalOrder {

    private final MomSrvMbdApiClient momSrvMbdApiClient;

    private final ImportMbdBomInfoMapper importMbdBomInfoMapper;

    private final ImportMbdPartInfoMapper importMbdPartInfoMapper;

    private final ImportMbdProcessPlanMapper importMbdProcessPlanMapper;

    private final ImportMbdOperationMapper importMbdOperationMapper;

    private final ImportMbdOrderMapper importMbdOrderMapper;

    private final OrderBomMapper orderBomMapper;

    private final OrderMapper orderMapper;

    private final OrderPhaseMapper orderPhaseMapper;

    private final ImportErpMappingMapper importErpMappingMapper;
    private final OrderAccessoriesMapper orderAccessoriesMapper;
    private final StringRedisTemplate stringRedisTemplate;
    private final CustomerMapper customerMapper;
    private final PhaseMapper phaseMapper;
    private final PhaseJobMapper phaseJobMapper;
    private final PhaseJobRefMapper phaseJobRefMapper;

    private final FactoryMapper factoryMapper;


    @Override
    public BasePageResVo<OrderExternalListResVo> externalList(OrderExternalListReqVo reqVo) {

        Page<ImportMbdOrder> importMbdOrderPage = importMbdOrderMapper.selectPage(reqVo.toPage(), Wrappers.<ImportMbdOrder>lambdaQuery().orderByDesc(ImportMbdOrder::getId));

        BasePageResVo<OrderExternalListResVo> resVo = BasePageResVo.of(importMbdOrderPage, OrderExternalListResVo.class);

        Map<Integer, ImportMbdOrder> collect = importMbdOrderPage.getRecords().stream().collect(Collectors.toMap(ImportMbdOrder::getId, Function.identity()));
        for (OrderExternalListResVo datum : resVo.getData()) {
            ImportMbdOrder mbdOrder = collect.get(datum.getId());
            datum.setMaterialCode(mbdOrder.getMaterCode());
            datum.setMaterialName(mbdOrder.getMaterName());
            datum.setOrderCode(mbdOrder.getOrderCode());
            datum.setOrderName(mbdOrder.getOrderName());
            datum.setPartCount(0);
            datum.setFactoryCode("170");
            datum.setOrderType(2);
        }

        return resVo;
    }

    @Override
    public BaseListResVo<OrderExternalBomResVo> externalBom(OrderExternalBomReqVo reqVo) {

        ImportMbdOrder mbdOrder = importMbdOrderMapper.selectById(reqVo.getId());

        List<ImportMbdBomInfo> importMbdBomInfos = importMbdBomInfoMapper.selectList(Wrappers.<ImportMbdBomInfo>lambdaQuery().eq(ImportMbdBomInfo::getOrderId, mbdOrder.getId()));

        List<ImportMbdPartInfo> importMbdPartInfos = importMbdPartInfoMapper.selectList(Wrappers.<ImportMbdPartInfo>lambdaQuery().eq(ImportMbdPartInfo::getOrderId, mbdOrder.getId()));

        String materCode = mbdOrder.getMaterCode();

        ImportMbdBomInfo topBom = importMbdBomInfos.stream().filter(e -> e.getSubPlmId().equals(materCode)).findFirst().orElseThrow(() -> SyExceptionUtils.e("没有找到plmId为{}的BOM", materCode));

        Map<String, ImportMbdPartInfo> partPlmIdMap = importMbdPartInfos.stream().collect(Collectors.toMap(ImportMbdPartInfo::getPlmId, Function.identity()));
        Map<String, List<ImportMbdBomInfo>> bomParentPlmIdMap = importMbdBomInfos.stream().collect(Collectors.groupingBy(ImportMbdBomInfo::getPlmId));

        List<OrderExternalBomResVo> resVos = new ArrayList<>();

        OrderExternalBomResVo top = swapLeftBom(mbdOrder, topBom, null, bomParentPlmIdMap, partPlmIdMap);
        resVos.add(top);

        List<OrderExternalBomResVo> temp = new ArrayList<>(resVos);
        while (CollUtil.isNotEmpty(temp)) {
            List<OrderExternalBomResVo> next = new ArrayList<>();
            for (OrderExternalBomResVo orderBom : temp) {
                List<ImportMbdBomInfo> orderBoms = bomParentPlmIdMap.get(orderBom.getMaterialCode());
                if (CollUtil.isNotEmpty(orderBoms)) {
                    for (ImportMbdBomInfo mbdBomInfo : orderBoms) {
                        OrderExternalBomResVo ob = swapLeftBom(mbdOrder, mbdBomInfo, orderBom, bomParentPlmIdMap, partPlmIdMap);
                        next.add(ob);
                    }
                }
            }
            resVos.addAll(next);
            temp = next;
        }

        return new BaseListResVo<>(resVos);
    }

    private OrderExternalBomResVo swapLeftBom(ImportMbdOrder mbdOrder, ImportMbdBomInfo bom, OrderExternalBomResVo parent, Map<String, List<ImportMbdBomInfo>> bomParentPlmIdMap, Map<String, ImportMbdPartInfo> partPlmIdMap) {

        OrderExternalBomResVo rr = new OrderExternalBomResVo();
        if (parent == null) {
            rr.setIsTop(1);
        } else {
            rr.setIsTop(0);
            rr.setPmCode(parent.getMaterialCode());
            rr.setPid(parent.getId());
        }


        ImportMbdPartInfo importMbdPartInfo = partPlmIdMap.get(bom.getSubPlmId());

        rr.setMaterialCode(importMbdPartInfo.getPlmId());
        rr.setMaterialName(importMbdPartInfo.getPartName());
        rr.setOrderCode(mbdOrder.getOrderCode());
        rr.setId(bom.getId());

        return rr;
    }

    @Override
    public BaseListResVo<OrderExternalDetailResVo> externalDetail(OrderExternalDetailReqVo reqVo) {

        ImportMbdBomInfo current = importMbdBomInfoMapper.selectById(reqVo.getId());

        ImportMbdOrder mbdOrder = importMbdOrderMapper.selectById(current.getOrderId());


        Order order = orderMapper.selectOne(Wrappers.<Order>lambdaQuery().eq(Order::getMaterCode, mbdOrder.getMaterCode()).eq(Order::getOrderCode, mbdOrder.getOrderCode()));
        List<OrderBom> orderBomList = orderBomMapper.selectList(Wrappers.<OrderBom>lambdaQuery().eq(OrderBom::getOrderId, order.getId()));

        OrderBom currentBom = orderBomList.stream().filter(e -> e.getMaterCode().equals(current.getSubPlmId())).findFirst().orElseThrow(() -> SyExceptionUtils.e("没有找到当前节点异常"));

        Map<Integer, List<OrderBom>> bomParentPlmIdMap = orderBomList.stream().filter(e -> e.getPid() != null).collect(Collectors.groupingBy(OrderBom::getPid));

        List<OrderExternalDetailResVo> resVos = new ArrayList<>();

        OrderExternalDetailResVo top = swapRightBom(currentBom);
        resVos.add(top);

        List<OrderExternalDetailResVo> temp = new ArrayList<>(resVos);
        while (CollUtil.isNotEmpty(temp)) {
            List<OrderExternalDetailResVo> next = new ArrayList<>();
            for (OrderExternalDetailResVo orderBom : temp) {
                List<OrderBom> orderBoms = bomParentPlmIdMap.get(orderBom.getId());
                if (CollUtil.isNotEmpty(orderBoms)) {
                    for (OrderBom mbdBomInfo : orderBoms) {
                        OrderExternalDetailResVo ob = swapRightBom(mbdBomInfo);
                        next.add(ob);
                    }
                }
            }
            resVos.addAll(next);
            temp = next;
        }


        return new BaseListResVo<>(resVos);
    }

    private OrderExternalDetailResVo swapRightBom(OrderBom bom) {
        OrderExternalDetailResVo rr = new OrderExternalDetailResVo();
        rr.setMaterCode(bom.getMaterCode());
        rr.setMaterName(bom.getMaterName());
        rr.setPlmId(bom.getPlmId());
        rr.setMaterHigh(bom.getMaterHigh());
        rr.setTexture(bom.getTexture());
        rr.setStandards(bom.getStandards());
        rr.setWorkChain(bom.getWorkChain());
        rr.setId(bom.getId());
        return rr;
    }

    @Transactional
    @Override
    public void externalSync(OrderExternalSyncReqVo reqVo) {

        List<OrderExternalSyncErrorResVo> errorList = new ArrayList<>();

        Map<String, Object> attr = reqVo.getAttr();
        String plmId = (String) attr.get("plmId");
        String constructNo = (String) attr.get("constructNo");
        String frameType = (String) attr.get("frameType");
        BomInfoTreeResDto tree = momSrvMbdApiClient.tree(plmId);

        // 清理所有数据
        if (tree.getCode().equals(1)) {
            throw SyExceptionUtils.e("MBD接口调用失败，错误信息：{}", tree.getMessage());
        }
        ImportMbdOrder oldOrder = importMbdOrderMapper.lambdaQuery().eq(ImportMbdOrder::getMaterCode, tree.getMaterCode()).eq(ImportMbdOrder::getOrderCode, tree.getOrderCode()).one();
        if (oldOrder != null) {
            importMbdOrderMapper.deleteReal(oldOrder.getId());
            importMbdBomInfoMapper.deleteReal(oldOrder.getId());
            importMbdPartInfoMapper.deleteReal(oldOrder.getId());
            importMbdProcessPlanMapper.deleteReal(oldOrder.getId());
        }

        Order order = orderMapper.getLastVersion(tree.getMaterCode(), tree.getOrderCode());
//        if (order != null) {
            //后期要进行版本比较，选择假删除
     /*      orderMapper.deleteReal(order.getId());
            orderBomMapper.deleteReal(order.getId());
            orderPhaseMapper.deleteReal(order.getId());
            orderAccessoriesMapper.deleteReal(order.getId());*/
//            orderMapper.deleteById(order.getId());
//            orderBomMapper.delete(Wrappers.<OrderBom>lambdaQuery().eq(OrderBom::getOrderId, order.getId()));
//            orderPhaseMapper.delete(Wrappers.<OrderPhase>lambdaQuery().eq(OrderPhase::getOrderId, order.getId()));
//            orderAccessoriesMapper.delete(Wrappers.<OrderAccessories>lambdaQuery().eq(OrderAccessories::getOrderId, order.getId()));
//
//            if (order.getOrderStatus() >= 6) {
//                // 清理倒排
//                reverseDetailMapper.deleteHard(order.getId());
//                reverseOrderMapper.deleteHard(order.getId());
//                reverseTopMapper.deleteHard(order.getId());
//
//                // 清理aps开头的表
//                apsOrderMapper.deleteOrderId(order.getId());
//                apsWorkOrderMapper.deleteOrderId(order.getId());
//                apsWorkDetailMapper.deleteOrderId(order.getId());
//                apsWorkDetailMapper.deleteOrderId(order.getId());
//            }
//        }

        ImportMbdOrder mbdOrder = new ImportMbdOrder();
        mbdOrder.setMaterCode(tree.getMaterCode());
        mbdOrder.setMaterName(tree.getMaterName());
        mbdOrder.setOrderCode(tree.getOrderCode());
        mbdOrder.setConstructNo(constructNo);
        mbdOrder.setOrderName(tree.getOrderName());
        mbdOrder.setOrderQty(100);
        importMbdOrderMapper.insert(mbdOrder);


        List<ImportMbdBomInfo> bomList = new ArrayList<>();
        // 保存到本地的日志
        if (CollUtil.isNotEmpty(tree.getBom())) {
            bomList = tree.getBom().stream().map(e -> {
                ImportMbdBomInfo importMbdBomInfo = MkBeanUtils.copyProperties(e, ImportMbdBomInfo.class);
                importMbdBomInfo.setOrderId(mbdOrder.getId());
                return importMbdBomInfo;
            }).collect(Collectors.toList());
            importMbdBomInfoMapper.insertBatchSomeColumn(bomList);
        }

        List<ImportMbdPartInfo> partList = new ArrayList<>();
        if (CollUtil.isNotEmpty(tree.getPart())) {
            Collection<ImportMbdPartInfo> values = tree.getPart().stream().map(e -> {
                ImportMbdPartInfo importMbdPartInfo = MkBeanUtils.copyProperties(e, ImportMbdPartInfo.class);
                importMbdPartInfo.setOrderId(mbdOrder.getId());
                return importMbdPartInfo;
            }).collect(Collectors.toMap(ImportMbdPartInfo::getPlmId, Function.identity(), (e1, e2) -> e1)).values();

            partList = new ArrayList<>(values);

            importMbdPartInfoMapper.insertBatchSomeColumn(partList);
        }

        List<ImportMbdProcessPlan> craftList = new ArrayList<>();
        if (CollUtil.isNotEmpty(tree.getCraft())) {
            craftList = tree.getCraft().stream().map(e -> {
                ImportMbdProcessPlan importMbdProcessPlan = MkBeanUtils.copyProperties(e, ImportMbdProcessPlan.class);
                importMbdProcessPlan.setOrderId(mbdOrder.getId());
                return importMbdProcessPlan;
            }).collect(Collectors.toList());
            importMbdProcessPlanMapper.insertBatchSomeColumn(craftList);
        }

        List<ImportMbdOperation> phaseList = new ArrayList<>();
        if (CollUtil.isNotEmpty(tree.getPhase())) {
            phaseList = tree.getPhase().stream().map(e -> {
                ImportMbdOperation importMbdOperation = MkBeanUtils.copyProperties(e, ImportMbdOperation.class);
                importMbdOperation.setOrderId(mbdOrder.getId());
                return importMbdOperation;
            }).collect(Collectors.toList());
            importMbdOperationMapper.insertBatchSomeColumn(phaseList);
        }

//        OrderAccessories


        // 整理缓存数据
        Map<String, List<ImportMbdBomInfo>> bomParentPlmIdMap = bomList.stream().collect(Collectors.groupingBy(ImportMbdBomInfo::getPlmId));
        Map<String, ImportMbdPartInfo> partPlmIdMap = partList.stream().filter(e -> StringUtils.hasText(e.getPlmId())).collect(Collectors.toMap(ImportMbdPartInfo::getPlmId, Function.identity(), (e1, e2) -> e1));
        Map<String, ImportMbdProcessPlan> craftProcessMap = craftList.stream().collect(Collectors.toMap(ImportMbdProcessPlan::getZmjLingzuJiandaihao, Function.identity()));
        Map<String, List<ImportMbdOperation>> phaseRouteMap = phaseList.stream().sorted(Comparator.comparing(ImportMbdOperation::getOperationLabel)).collect(Collectors.groupingBy(ImportMbdOperation::getProcessRouteNumber));
        List<ImportErpMapping> importErpMappings = importErpMappingMapper.selectList(null);
        Map<String, Map<String, List<ImportErpMapping>>> phaseOpCodePhaseNameMap = importErpMappings.stream().filter(e -> StringUtils.hasText(e.getErpOpCode()) && StringUtils.hasText(e.getErpPhaseName())).collect(Collectors.groupingBy(ImportErpMapping::getErpOpCode, Collectors.groupingBy(ImportErpMapping::getErpPhaseName)));


        ImportMbdBomInfo importMbdBomInfo = bomList.stream().filter(e -> e.getSubPlmId().equals(plmId)).findFirst().orElseThrow(() -> SyExceptionUtils.e("没有找到plmId为{}的BOM", plmId));

        Order o = swapOrder(mbdOrder, importMbdBomInfo, partPlmIdMap, errorList);
        o.setLastPullDateTime(LocalDateTime.now());
        o.setFrameType(frameType);
        if (order != null) {
            if (order.getVersion() == null) {
                o.setVersion(1);
            } else {
                o.setVersion(order.getVersion() + 1);
            }
        } else {
            o.setVersion(1);
        }
        String suffix = OrderUtils.partType(o.getPlmId(), o.getMaterName());
        o.setSuffix(suffix);
        orderMapper.insert(o);
  /*      if (order != null) {
            o.setId(order.getId());
            o.setLastPullDateTime(LocalDateTime.now());
            if (order.getVersion() == null) {
                o.setVersion(1);
            } else {
                o.setVersion(order.getVersion() + 1);
            }
            orderMapper.updateById(o);

        } else {

        }*/



        // 处理父子关系,并保存
        OrderBom bom = swapOrderBom(o, null, importMbdBomInfo, partPlmIdMap, craftProcessMap, phaseRouteMap, phaseOpCodePhaseNameMap, errorList);
        List<OrderBom> newBomList = new ArrayList<>();
        newBomList.add(bom);
        orderBomMapper.insert(bom);

        List<OrderBom> temp = new ArrayList<>(newBomList);

        while (CollUtil.isNotEmpty(temp)) {
            List<OrderBom> next = new ArrayList<>();
            for (OrderBom orderBom : temp) {
                List<ImportMbdBomInfo> orderBoms = bomParentPlmIdMap.get(orderBom.getMaterCode());
                if (CollUtil.isNotEmpty(orderBoms)) {
                    for (ImportMbdBomInfo mbdBomInfo : orderBoms) {
                        OrderBom ob = swapOrderBom(o, orderBom, mbdBomInfo, partPlmIdMap, craftProcessMap, phaseRouteMap, phaseOpCodePhaseNameMap, errorList);
                        if (ob == null) {
                            continue;
                        }
                        next.add(ob);
                    }
                }
            }
            newBomList.addAll(next);
            temp = next;

            if (CollUtil.isNotEmpty(temp)) {
                orderBomMapper.insertBatchSomeColumn(temp);
            }
        }

        Map<String, List<PhaseJob>> phaseJobMap = getPhaseJob();

        // 查找所有节点的工序并保存
        List<OrderPhase> orderPhaseList = new ArrayList<>();
        List<PhaseAccessoriesWrap> orderAccessoriesList = new ArrayList<>();
        Map<Integer, OrderBom> orderBomMap = newBomList.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));
        for (OrderBom orderBom : newBomList) {
            if (orderBom.getWorkChain() == null) {
                errorList.add(new OrderExternalSyncErrorResVo(4, "零件[" + orderBom.getMaterCode() + "],[" + orderBom.getMaterName() + "]没有工序", o.getConstructNo(), orderBom.getWorkOrderCode(), orderBom.getMaterCode(), orderBom.getMaterName(), orderBom.getPlmId(), orderBom.getStandards(), orderBom.getPartCount().toString(), orderBom.getErpParentCode(), null, orderBom.getDrawing()));
                continue;
            }
            if (orderBom.getWorkChain().equals("WL")) {
                continue;
            }
            swapOrderPhase(o, orderBom, craftProcessMap, phaseRouteMap, phaseOpCodePhaseNameMap, orderPhaseList, orderAccessoriesList, orderBomMap, errorList, phaseJobMap);
//            List<OrderPhase> orderPhaseList1 =
//            orderPhaseList.addAll(orderPhaseList1);
        }

        if (CollUtil.isNotEmpty(orderPhaseList)) {
            orderPhaseMapper.insertBatchSomeColumn(orderPhaseList);
        }

        if (CollUtil.isNotEmpty(orderAccessoriesList)) {
            List<OrderAccessories> collect = orderAccessoriesList.stream()
                    .map(e -> {
                        e.getOrderAccessories().setPhaseId(e.getOrderPhase().getId());
                        return e.getOrderAccessories();
                    }).collect(Collectors.toList());

            orderAccessoriesMapper.insertBatchSomeColumn(collect);
        }

        String key = "mom-srv-aps:order-sync:error:" + o.getMaterCode() + ":" + o.getMaterCode();
        if (CollUtil.isNotEmpty(errorList)) {
            // 存redis
            stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(errorList), 2, TimeUnit.DAYS);

            throw SyExceptionUtils.e("同步失败，请查看Excel的错误信息");
        }
        stringRedisTemplate.delete(key);

        try {
            NestRule nestRule = SpringUtil.getBean("lantekPreNestRule");
            List<OrderBom> orderBomList = orderBomMapper.lambdaQuery().eq(OrderBom::getOrderId, o.getId()).eq(OrderBom::getMaterType, "Platepart").list();
            nestRule.partAdd(orderBomList);
        } catch (Exception e) {
            log.info("零件图纸同步失败。");
        }

    }

    public Map<String, List<PhaseJob>> getPhaseJob() {
        List<Phase> phaseList = phaseMapper.lambdaQuery().list();
        Map<Integer, Phase> phaseIdMap = phaseList.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));

        List<PhaseJob> phaseJobList = phaseJobMapper.lambdaQuery().list();
        Map<Integer, PhaseJob> phaseJobIdMap = phaseJobList.stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));

        List<PhaseJobRef> phaseJobRefList = phaseJobRefMapper.lambdaQuery().list();
        Map<String, List<PhaseJobRef>> phaseCodeRefJob = phaseJobRefList.stream().sorted(Comparator.comparing(PhaseJobRef::getSeq)).collect(Collectors.groupingBy(e -> phaseIdMap.get(e.getPhaseId()).getMyCode(), LinkedHashMap::new, Collectors.toList()));
        Map<String, List<PhaseJob>> phaseJobMap = new HashMap<>();
        for (String s : phaseCodeRefJob.keySet()) {
            phaseJobMap.put(s, new ArrayList<>());
            List<PhaseJobRef> phaseJobRefs = phaseCodeRefJob.get(s);
            if (CollUtil.isNotEmpty(phaseJobRefs)) {
                phaseJobMap.put(s, phaseJobRefs.stream()
                        .sorted(Comparator.comparing(PhaseJobRef::getSeq))
                        .map(e -> phaseJobIdMap.get(e.getPhaseJobId()))
                        .collect(Collectors.toList()));
            }
        }
        return phaseJobMap;
    }

    public void swapOrderPhase(Order order, OrderBom orderBom, Map<String, ImportMbdProcessPlan> craftProcessMap, Map<String, List<ImportMbdOperation>> phaseRouteMap, Map<String, Map<String, List<ImportErpMapping>>> phaseOpCodePhaseNameMap, List<OrderPhase> orderPhaseList, List<PhaseAccessoriesWrap> orderAccessoriesList, Map<Integer, OrderBom> orderBomMap, List<OrderExternalSyncErrorResVo> errorList, Map<String, List<PhaseJob>> phaseJobMap) {

        ImportMbdProcessPlan importMbdProcessPlan = craftProcessMap.get(orderBom.getMaterCode());
        if (importMbdProcessPlan == null) {
            return;
        }

        List<ImportMbdOperation> importMbdOperations = phaseRouteMap.get(importMbdProcessPlan.getProcessRouteNumber());
        importMbdOperations.sort((e1, e2) -> {
            Integer i1 = Integer.parseInt(e1.getOperationLabel());
            Integer i2 = Integer.parseInt(e2.getOperationLabel());
            return i1.compareTo(i2);
        });

        if (CollUtil.isEmpty(importMbdOperations)) {
            return;
        }

        List<OrderPhase> currentOrderPhases = new ArrayList<>();
        int index = 0;
        Map<String, Integer> phaseCount = new HashMap<>();
        for (ImportMbdOperation importMbdOperation : importMbdOperations) {
            if (importMbdOperation.getZmjShiDongGongshi().equals(BigDecimal.ZERO)) {
                continue;
            }

            ImportErpMapping importErpMapping = null;
            try {
                importErpMapping = phaseOpCodePhaseNameMap.get(importMbdOperation.getZmjGongzuoZhongxin()).get(importMbdOperation.getOperationName()).get(0);
            } catch (NullPointerException ex) {
//                throw SyExceptionUtils.e("零件[{}]在映射表中没有找到工作中心为[{}], 工序名称为[{}]的数据", orderBom.getMaterCode(), importMbdOperation.getZmjGongzuoZhongxin(), importMbdOperation.getOperationName());
//                errorList.add(new OrderExternalSyncErrorResVo(4, "零件[" + orderBom.getMaterCode() + "]在映射表中没有找到工作中心为[" + importMbdOperation.getZmjGongzuoZhongxin() + "], 工序名称为[" + importMbdOperation.getOperationName() + "]的数据"));
                errorList.add(new OrderExternalSyncErrorResVo(4, "零件[" + orderBom.getMaterCode() + "]在映射表中没有找到工作中心为[" + importMbdOperation.getZmjGongzuoZhongxin() + "], 工序名称为[" + importMbdOperation.getOperationName() + "]的数据", order.getConstructNo(), orderBom.getWorkOrderCode(), orderBom.getMaterCode(), orderBom.getMaterName(), orderBom.getPlmId(), orderBom.getStandards(), orderBom.getPartCount().toString(), orderBom.getErpParentCode(), null, orderBom.getDrawing()));
                continue;
            }
            OrderPhase phase = new OrderPhase();
            phase.setOrderId(order.getId());
            phase.setBomId(orderBom.getId());
            phase.setMaterName(orderBom.getMaterName());
            phase.setMaterNo(orderBom.getMaterCode());
            phase.setWorkTime(importMbdOperation.getZmjShiDongGongshi().multiply(new BigDecimal(60)).setScale(0, RoundingMode.UP).intValue());
            phase.setOriWorkTime(phase.getWorkTime());
            phase.setWorkGroupNumber(importErpMapping.getMesWorkCenter());
            phase.setPhaseName(importErpMapping.getApsPhaseName());

            Integer count = phaseCount.compute(importErpMapping.getMesWorkPhase(), (k, v) -> v == null ? 0 : v + 1);
            if (count > 1) {
                phase.setPhaseCode(importErpMapping.getMesWorkPhase() + String.format("%02d", count));
            } else {
                phase.setPhaseCode(importErpMapping.getMesWorkPhase());
            }

            phase.setPhaseSeq(index + 1);
//            ll.add(phase);

            if (phase.getWorkTime().compareTo(0) > 0) {
                // 工序任务处理
                List<PhaseJob> job = phaseJobMap.get(phase.getPhaseCode());
                if (CollUtil.isNotEmpty(job)) {
                    int jobTime = TaskTimeUtils.calcJobTime(phase, job);
                    phase.setWorkTime(phase.getWorkTime() + jobTime);
                }
            }
            currentOrderPhases.add(phase);

            index++;

            if (new BigDecimal(importMbdOperation.getWireQuota()).compareTo(BigDecimal.ZERO) > 0) {

                OrderAccessories oa = new OrderAccessories();
                oa.setOrderId(order.getId());
                oa.setBomId(orderBom.getId());
                oa.setType(1);
                oa.setSpec(importMbdOperation.getWireModel());
                oa.setModel(importMbdOperation.getWireNumber());
                oa.setPartCount(new BigDecimal(importMbdOperation.getWireQuota()));

                PhaseAccessoriesWrap wrap = new PhaseAccessoriesWrap();
                wrap.setOrderAccessories(oa);
                wrap.setOrderPhase(phase);
                orderAccessoriesList.add(wrap);

            }

        }

        long count = currentOrderPhases.stream().filter(e -> e.getPhaseCode().equals("JG") || e.getPhaseCode().equals("HG")).count();
        if (count > 0) {
            if (orderBom.getMaterType().equals("Platepart")) {
                OrderPhase phase = PhaseUtils.genLingliaoPhase(
                        order.getId(), orderBom.getId(), orderBom.getWorkChain(),
                        1, orderBom.getPlmId(), orderBom.getMaterName()
                );
//
//                phase.setOrderId(order.getId());
//                phase.setBomId(orderBom.getId());
//                phase.setWorkTime(0);
//                phase.setOriWorkTime(phase.getWorkTime());
//                phase.setWorkChain(orderBom.getWorkChain());
//                phase.setPhaseSeq(1);
//                phase.setMaterNo(orderBom.getPlmId());
//                phase.setMaterName(orderBom.getMaterName());
//                phase.setPhaseCode(WorkshopProp.LL_PHASE_CODE);
//                phase.setPhaseName(WorkshopProp.LL_PHASE_NAME);
//                phase.setWorkGroupNumber(WorkshopProp.LL_GROUP);

                currentOrderPhases.add(0, phase);
            }
        }

        if (orderBom.getPid() != null) {
            if (orderBom.getMaterType().equals("Platepart") || (orderBom.getMaterType().equals("Assembly") && !MkPartUtils.supportKjPhase(orderBom.getPlmId(), orderBom.getMaterName()))) {
                OrderBom parentBom = orderBomMap.get(orderBom.getPid());
                if (MkPartUtils.supportKjPhase(parentBom.getPlmId(), parentBom.getMaterName())) {
                    OrderPhase phase = PhaseUtils.genLingliaoPhase(
                            order.getId(), orderBom.getId(), orderBom.getWorkChain(),
                            index + 1, orderBom.getPlmId(), orderBom.getMaterName()
                    );

                    index++;

//                    phase.setOrderId(order.getId());
//                    phase.setBomId(orderBom.getId());
//                    phase.setWorkTime(1);
//                    phase.setOriWorkTime(phase.getWorkTime());
//                    phase.setWorkChain(orderBom.getWorkChain());
//                    phase.setPhaseSeq(index + 1);
//
//                    phase.setMaterNo(orderBom.getPlmId());
//                    phase.setMaterName(orderBom.getMaterName());
//                    phase.setPhaseCode(WorkshopProp.KJ_PHASE_CODE);
//                    phase.setPhaseName(WorkshopProp.KJ_PHASE_NAME);
//                    phase.setWorkGroupNumber(WorkshopProp.KJ_GROUP);

                    currentOrderPhases.add(phase);
                }
            }
        }

        for (int i = 0; i < currentOrderPhases.size(); i++) {
            currentOrderPhases.get(i).setPhaseSeq(i + 1);
        }

        orderPhaseList.addAll(currentOrderPhases);

    }

    public Order swapOrder(ImportMbdOrder mbdOrder, ImportMbdBomInfo importMbdBomInfo, Map<String, ImportMbdPartInfo> partPlmIdMap, List<OrderExternalSyncErrorResVo> errorList) {
        Order order = new Order();
        order.setMaterCode(mbdOrder.getMaterCode());
        order.setMaterName(mbdOrder.getMaterName());
        order.setOrderCode(mbdOrder.getOrderCode());
        order.setOrderName(mbdOrder.getOrderName());
        order.setConstructNo(mbdOrder.getConstructNo());
        order.setOrderQty(mbdOrder.getOrderQty());
        order.setFactoryCode("170");
        order.setOrderType(2);
        order.setFactoryId(1);
        order.setOrderStatus(1);


        Customer customer = customerMapper.selectById(3);
        if (customer == null) {
            throw SyExceptionUtils.e("没有找到该客户");
        }

        order.setCustomerId(3);
        order.setCustomerCode(customer.getMyCode());
        order.setCustomerName(customer.getName());
        order.setOrderPriority(1);
        order.setOrderWeight(1);

        ImportMbdPartInfo importMbdPartInfo = partPlmIdMap.get(importMbdBomInfo.getSubPlmId());

        if (importMbdPartInfo == null) {
//            errorList.add(new OrderExternalSyncErrorResVo(1, "没有找到plmId为" + importMbdBomInfo.getSubPlmId() + "的零件"));
            errorList.add(new OrderExternalSyncErrorResVo(1, "没有找到plmId为" + importMbdBomInfo.getSubPlmId() + "的零件", order.getConstructNo(), null, null, null, null, null, null, null, null, null));
            throw SyExceptionUtils.e("没有找到plmId为{}的零件", importMbdBomInfo.getSubPlmId());
        }

        order.setPlmId(importMbdPartInfo.getPlmIdNew());

        Factory line = factoryMapper.lambdaQuery().eq(Factory::getType, 2).eq(Factory::getMyCode, WorkshopProp.DEFAULT_LINE_CODE).one();
        order.setLineId(line.getId());

        return order;
    }

    public OrderBom swapOrderBom(Order order, OrderBom parent, ImportMbdBomInfo current, Map<String, ImportMbdPartInfo> partPlmIdMap, Map<String, ImportMbdProcessPlan> craftProcessMap, Map<String, List<ImportMbdOperation>> phaseRouteMap, Map<String, Map<String, List<ImportErpMapping>>> phaseOpCodePhaseNameMap, List<OrderExternalSyncErrorResVo> errorList) {

        OrderBom ob = new OrderBom();
        ob.setOrderId(order.getId());
        ob.setPartCount(new BigDecimal(current.getAmount()));
        if (parent == null) {
            ob.setTotalCount(new BigDecimal(1));
            ob.setLevel(1);
        } else {
            ob.setLevel(parent.getLevel() + 1);
            ob.setPid(parent.getId());
            ob.setTopFlag(1);
            ob.setTotalCount(ob.getPartCount().multiply(parent.getTotalCount()));
        }

        ImportMbdPartInfo importMbdPartInfo = partPlmIdMap.get(current.getSubPlmId());

        if (importMbdPartInfo == null) {
//            errorList.add(new OrderExternalSyncErrorResVo(3, "工单明细中，实动工时总和为0，请检查工单明细！", order.getConstructNo(), ob.getWorkOrderCode(), ob.getMaterCode(), ob.getMaterName(), ob.getPlmId(), ob.getStandards(), ob.getPartCount().toString(), ob.getErpParentCode(), null, ob.getDrawing()));
            return null;
//            return ob;
//            throw SyExceptionUtils.e("没有找到plmId为{}的零件", current.getSubPlmId());
        }

        ImportMbdProcessPlan importMbdProcessPlan = craftProcessMap.get(importMbdPartInfo.getPlmId());


        if (importMbdPartInfo.getSource().equals("A")) {

            if (StringUtils.hasText(importMbdPartInfo.getCailiao()) && importMbdPartInfo.getCailiao().contains("δ")) {

                try {
                    Integer.parseInt(importMbdPartInfo.getCailiao().split("δ")[1].trim());
                } catch (Exception e) {
//                    errorList.add(new OrderExternalSyncErrorResVo(3, importMbdPartInfo.getPartName() + "零件，PLMID " + importMbdPartInfo.getPlmId() + " 厚度有问题,不是数字: " + importMbdPartInfo.getCailiao(), order.getConstructNo(), ob.getWorkOrderCode(), ob.getMaterCode(), ob.getMaterName(), ob.getPlmId(), ob.getStandards(), ob.getPartCount().toString(), ob.getErpParentCode(), null, ob.getDrawing()));
                    return null;
//                    return ob;
//                    throw SyExceptionUtils.e("{}零件，PLMID {} 厚度有问题,不是数字: {}", importMbdPartInfo.getPartName(), importMbdPartInfo.getPlmId(), importMbdPartInfo.getCailiao());
                }
            }
            if (StringUtils.hasText(importMbdPartInfo.getCailiao()) && importMbdPartInfo.getCailiao().contains("δ") && importMbdPartInfo.getCailiao().split("δ").length == 2 && Integer.parseInt(importMbdPartInfo.getCailiao().split("δ")[1].trim()) < 12) {
                // 小于12的板厚，即使是板材也认为是外购件
                ob.setWorkChain("WL");
                ob.setReadyType(2);
                ob.setMaterType("Component");
            } else if (importMbdProcessPlan == null && !importMbdPartInfo.getCailiao().contains("δ")) { // 没有工艺，并且不包含δ
                ob.setWorkChain("WL");
                ob.setReadyType(2);
                ob.setMaterType("Component");
            } else if (importMbdPartInfo.getPartName().contains("柱窝")) {
                ob.setWorkChain("WL");
                ob.setReadyType(2);
                ob.setMaterType("Component");
            } else {
                if (importMbdProcessPlan == null) {
//                    errorList.add(new OrderExternalSyncErrorResVo(3, importMbdPartInfo.getPartName() + "零件，PLMID " + importMbdPartInfo.getPlmId() + "，的工艺路线丢失，通知MBD通过CAPP推送数据至MES"));
//                    errorList.add(new OrderExternalSyncErrorResVo(3, importMbdPartInfo.getPartName() + "零件，PLMID " + importMbdPartInfo.getPlmId() + "，的工艺路线丢失，通知MBD通过CAPP推送数据至MES", order.getConstructNo(), ob.getWorkOrderCode(), ob.getMaterCode(), ob.getMaterName(), ob.getPlmId(), ob.getStandards(), ob.getPartCount().toString(), ob.getErpParentCode(), null, ob.getDrawing()));
                    return null;
//                    throw SyExceptionUtils.e("{}零件，PLMID {}，的工艺路线丢失，通知MBD通过CAPP推送数据至MES", importMbdPartInfo.getPartName(), importMbdPartInfo.getPlmId());
//                    return ob;
                }
                List<ImportMbdOperation> importMbdOperations = phaseRouteMap.get(importMbdProcessPlan.getProcessRouteNumber());
                if (CollUtil.isEmpty(importMbdOperations)) {
//                    errorList.add(new OrderExternalSyncErrorResVo(3, importMbdPartInfo.getPartName() + "零件，PLMID " + importMbdPartInfo.getPlmId() + "，的工艺路线丢失，通知MBD通过CAPP推送数据至MES"));
//                    errorList.add(new OrderExternalSyncErrorResVo(3, importMbdPartInfo.getPartName() + "零件，PLMID " + importMbdPartInfo.getPlmId() + "，的工艺路线丢失，通知MBD通过CAPP推送数据至MES", order.getConstructNo(), ob.getWorkOrderCode(), ob.getMaterCode(), ob.getMaterName(), ob.getPlmId(), ob.getStandards(), ob.getPartCount().toString(), ob.getErpParentCode(), null, ob.getDrawing()));
                    return null;
//                    throw SyExceptionUtils.e("{}零件，PLMID {}，的工艺路线丢失，通知MBD通过CAPP推送数据至MES", importMbdPartInfo.getPartName(), importMbdPartInfo.getPlmId());
                }


                String collect = importMbdOperations.stream().filter(e -> !e.getZmjShiDongGongshi().equals(new BigDecimal(0))).sorted((e1, e2) -> {
                    Integer i1 = Integer.parseInt(e1.getOperationLabel());
                    Integer i2 = Integer.parseInt(e2.getOperationLabel());
                    return i1.compareTo(i2);
                }).map(e -> {
                    if (phaseOpCodePhaseNameMap.get(e.getZmjGongzuoZhongxin()) == null || phaseOpCodePhaseNameMap.get(e.getZmjGongzuoZhongxin()).get(e.getOperationName()) == null) {
//                        errorList.add(new OrderExternalSyncErrorResVo(4, "零件[" + importMbdPartInfo.getPlmId() + "]的工作中心[" + e.getZmjGongzuoZhongxin() + "], [" + e.getOperationName() + "]不存在，核对工序链"));
//                                throw SyExceptionUtils.e("零件[{}]的工作中心[{}], [{}]不存在，核对工序链", importMbdPartInfo.getPlmId(), e.getZmjGongzuoZhongxin(), e.getOperationName());
                        errorList.add(new OrderExternalSyncErrorResVo(4, "零件[" + importMbdPartInfo.getPlmId() + "]的工作中心[" + e.getZmjGongzuoZhongxin() + "], [" + e.getOperationName() + "]不存在，核对工序链", order.getConstructNo(), ob.getWorkOrderCode(), ob.getMaterCode(), ob.getMaterName(), ob.getPlmId(), ob.getStandards(), ob.getPartCount().toString(), ob.getErpParentCode(), null, ob.getDrawing()));
                    }
                    if (phaseOpCodePhaseNameMap.get(e.getZmjGongzuoZhongxin()).get(e.getOperationName()) == null) {
//                        throw SyExceptionUtils.e("零件[{}]的工作中心[{}], [{}]不存在，核对工序链", importMbdPartInfo.getPlmId(), e.getZmjGongzuoZhongxin(), e.getOperationName());
                        errorList.add(new OrderExternalSyncErrorResVo(4, "零件[" + importMbdPartInfo.getPlmId() + "]的工作中心[" + e.getZmjGongzuoZhongxin() + "], [" + e.getOperationName() + "]不存在，核对工序链", order.getConstructNo(), ob.getWorkOrderCode(), ob.getMaterCode(), ob.getMaterName(), ob.getPlmId(), ob.getStandards(), ob.getPartCount().toString(), ob.getErpParentCode(), null, ob.getDrawing()));
//                        errorList.add(new OrderExternalSyncErrorResVo(4, "零件[" + importMbdPartInfo.getPlmId() + "]的工作中心[" + e.getZmjGongzuoZhongxin() + "], [" + e.getOperationName() + "]不存在，核对工序链", order.getConstructNo(), ob.getWorkOrderCode(), ob.getMaterCode(), ob.getMaterName(), ob.getPlmId(), ob.getStandards(), ob.getPartCount().toString(), ob.getErpParentCode(), null, ob.getDrawing()));


                    }
                    List<ImportErpMapping> importErpMappings = phaseOpCodePhaseNameMap.get(e.getZmjGongzuoZhongxin()).get(e.getOperationName());
                    ImportErpMapping importErpMapping = new ImportErpMapping();
                    if (!CollUtil.isEmpty(importErpMappings)) {
                        importErpMapping = importErpMappings.get(0);
                    }


                    return importErpMapping.getMesWorkPhase();
                }).collect(Collectors.joining("-"));

                String[] split = collect.split("-");
                Map<String, Integer> phaseCount = new HashMap<>();
                StringBuilder sb = new StringBuilder();
                for (String s : split) {
                    Integer count = phaseCount.compute(s, (k, v) -> v == null ? 0 : v + 1);
                    sb.append("-").append(s);
                    if (count > 1) {
                        sb.append(String.format("%02d", count));
                    }
                }
                sb.deleteCharAt(0);

                ob.setWorkChain(sb.toString());
                ob.setReadyType(1);
                if (ob.getWorkChain().contains("JG") || ob.getWorkChain().contains("HG")) {
                    ob.setMaterType("Platepart");
                } else {
                    ob.setMaterType("Assembly");
                }
            }

        } else if (importMbdPartInfo.getSource().equals("B")) {
            if (importMbdProcessPlan != null) {
//                throw SyExceptionUtils.e("{}零件，PLMID {}外购件有工艺，请确认外购件类型", importMbdPartInfo.getPartName(), importMbdPartInfo.getPlmId());
//                errorList.add(new OrderExternalSyncErrorResVo(4, importMbdPartInfo.getPartName() + "零件，PLMID " + importMbdPartInfo.getPlmId() + "外购件有工艺，请确认外购件类型"));
                errorList.add(new OrderExternalSyncErrorResVo(4, importMbdPartInfo.getPartName() + "零件，PLMID " + importMbdPartInfo.getPlmId() + "外购件有工艺，请确认外购件类型", order.getConstructNo(), ob.getWorkOrderCode(), ob.getMaterCode(), ob.getMaterName(), ob.getPlmId(), ob.getStandards(), ob.getPartCount().toString(), ob.getErpParentCode(), null, ob.getDrawing()));


            }
            //  判断来源B是否有工艺路线，直接提醒出来，看是否工线路线写完，没有工序。
            ob.setWorkChain("WL");
            ob.setReadyType(2);
        } else {
            errorList.add(new OrderExternalSyncErrorResVo(4, importMbdPartInfo.getPartName() + "零件，PLMID " + importMbdPartInfo.getPlmId() + "外购件有工艺，请确认外购件类型", order.getConstructNo(), ob.getWorkOrderCode(), ob.getMaterCode(), ob.getMaterName(), ob.getPlmId(), ob.getStandards(), ob.getPartCount().toString(), ob.getErpParentCode(), null, ob.getDrawing()));
//            errorList.add(new OrderExternalSyncErrorResVo(4, importMbdPartInfo.getPartName() + "零件，PLMID " + importMbdPartInfo.getPlmId() + "，未知的来源字段，通知MBD通过CAPP推送数据至MES"));

//            throw SyExceptionUtils.e("{}零件，PLMID {}，未知的来源字段，通知MBD通过CAPP推送数据至MES", importMbdPartInfo.getPartName(), importMbdPartInfo.getPlmId());
        }


        ob.setMaterCode(importMbdPartInfo.getPlmId());
        ob.setMaterName(importMbdPartInfo.getPartName());

        ob.setFactoryNo(String.valueOf(current.getFactoryId()));
//        ob.setPackCenter(importMbdPartInfo.getUnit());
        ob.setStandards(importMbdPartInfo.getCailiao());
        ob.setPlmId(importMbdPartInfo.getPlmIdNew());
        if (StringUtils.hasText(importMbdPartInfo.getWeight())) {
            ob.setMaterWeight(new BigDecimal(importMbdPartInfo.getWeight()));
        }

        ob.setBomCode(current.getSubPlmId());
        ob.setParentBomCode(current.getPlmId());

//        phaseOpCodePhaseNameMap.get(current.get)
//        ob.setWorkChain();

        if (parent == null) {
            ob.setAssemblyPath("/" + order.getId() + "/" + ob.getPlmId());
        } else {
            ob.setAssemblyPath(parent.getAssemblyPath() + "/" + ob.getPlmId());
        }

        return ob;
    }

    @Override
    public String getMyCode() {
        return MBD_CODE;
    }
}
